local skel = fk.CreateSkill {
  name = "emo__ziduolh",
  tags = {Skill.Switch},
}

Fk:loadTranslationTable{
  ["emo__ziduolh"] = "自堕轮回阿鼻",
  [":emo__ziduolh"] = "转换技，你可以将①锦囊牌当作任意基本牌，②基本牌当作此法转化过的对应锦囊牌使用或打出，然后若你手牌数为众数，调整为另一抵达过的众数。",

  [":emo__ziduolh_yang"] = "转换技，你可以将<font color='#E0DB2F'>①锦囊牌当作任意基本牌，</font><font color='grey'>②基本牌当作此法转化过的对应锦囊牌</font>使用或打出，然后若你手牌数为众数，调整为另一抵达过的众数。",
  [":emo__ziduolh_yin"] = "转换技，你可以将<font color='grey'>①锦囊牌当作任意基本牌，</font><font color='#E0DB2F'>②基本牌当作此法转化过的对应锦囊牌</font>使用或打出，然后若你手牌数为众数，调整为另一抵达过的众数。",

  ["#emo__ziduolh-yang"] = "锦囊牌当作任意基本牌使用或打出",
  ["#emo__ziduolh-yin"] = "基本牌当作此法转化过的锦囊牌使用或打出",
  ["#emo__ziduolh-vs"] = "[%arg2]当作【%arg】使用",
  ["#emo__ziduolh-choice"] = "选择一个数值，将手牌调整至此值",
  ["@emo__ziduolh_mode"] = "众数",
}

--- 可以转化的牌名
---@param player Player
local getNames = function (player)
  local names = {}
  if player:getSwitchSkillState(skel.name) == fk.SwitchYang then
    names = Fk:getAllCardNames("b")
  else
    for _, v in pairs(player:getTableMark("emo__ziduolh_record")) do
      table.insertTableIfNeed(names, v)
    end
  end
  return player:getViewAsCardNames(skel.name, names)
end

--- 我的手牌数是否为众数
---@param player Player
local modeValue = function (player)
  local numMap = {}
  for _, p in ipairs(Fk:currentRoom().alive_players) do
    local num = p:getHandcardNum()
    numMap[num] = (numMap[num] or 0) + 1
  end
  local hand = player:getHandcardNum()
  local max, min, nums = 0, hand, {}
  for k, v in pairs(numMap) do
    max = math.max(max, v)
    min = math.min(min, v)
    table.insertIfNeed(nums, k)
  end
  if min == max and #nums > 1 then return nil end -- 所有数出现频率一直时，无众数
  local maxs = {}
  for k, v in pairs(numMap) do
    if v == max then
      table.insert(maxs, k)
    end
  end
  if not table.contains(maxs, hand) then return nil end
  return hand
end

skel:addEffect("viewas", {
  pattern = ".|.|.|.|.|trick,basic",
  prompt = function (self, player, selected_cards, selected)
    if player:getSwitchSkillState(skel.name) == fk.SwitchYang then
      return "#emo__ziduolh-yang"
    else
      local trickName = self.interaction.data
      if trickName == nil then return " " end
      local names = {}
      for name, v in pairs(player:getTableMark("emo__ziduolh_record")) do
        if table.contains(v, trickName) then
          table.insert(names, name)
        end
      end
      names = table.map(names, function (name)
        return Fk:translate(name)
      end)
      return "#emo__ziduolh-vs:::" .. trickName .. ":" .. table.concat(names, "/")
    end
  end,
  handly_pile = true,
  interaction = function(self, player)
    local choices = getNames(player)
    if #choices > 0 then
      return UI.CardNameBox { choices = choices }
    end
  end,
  card_filter = function (self, player, to_select, selected)
    if #selected ~= 0 then return false end
    if player:getSwitchSkillState(skel.name) == fk.SwitchYang then
      return Fk:getCardById(to_select).type == Card.TypeTrick
    else
      local mark = player:getTableMark("emo__ziduolh_record")
      local basicName, trickName = Fk:getCardById(to_select).trueName, self.interaction.data
      return table.contains(mark[basicName] or {}, trickName)
    end
  end,
  view_as = function (self, player, cards)
    if #cards ~= 1 or Fk.all_card_types[self.interaction.data] == nil then return nil end
    local c = Fk:cloneCard(self.interaction.data)
    c.skillName = skel.name
    c:addSubcard(cards[1])
    return c
  end,
  before_use = function(self, player, use)
    local room = player.room
    if use.card.type == Card.TypeBasic then
      local mark = player:getTableMark("emo__ziduolh_record")
      local basicName, trickName = use.card.trueName, Fk:getCardById(use.card.subcards[1]).trueName
      mark[basicName] = mark[basicName] or {}
      table.insertIfNeed(mark[basicName], trickName)
      room:setPlayerMark(player, "emo__ziduolh_record", mark)
    end
  end,
  after_use = function (self, player, use)
    if player.dead then return end
    local room = player.room
    local num = modeValue(player)
    if not num then return end
    local mark = player:getTableMark("@emo__ziduolh_mode")
    table.removeOne(mark, num)
    if #mark == 0 then return end
    table.sort(mark)
    mark = table.map(mark, tostring)
    num = tonumber(room:askToChoice(player, {
      choices = mark, skill_name = skel.name, prompt = "#emo__ziduolh-choice"
    }))
    num = player:getHandcardNum() - num
    if num > 0 then
      room:askToDiscard(player, {min_num = num, max_num = num, include_equip = false, skill_name = skel.name, cancelable = false})
    else
      player:drawCards(-num, skel.name)
    end
  end,
  enabled_at_play = function(self, player)
    return #getNames(player) > 0
  end,
  enabled_at_response = function (self, player, response)
    return #getNames(player) > 0
  end,
})

--[[
skel:addEffect(fk.AfterCardsMove, {
  is_delay_effect = true, -- 为了不转换，无敌了！
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(skel.name) or not modeValue(player) or #player:getTableMark("@emo__ziduolh_mode") < 2 then return false end
    for _, move in ipairs(data) do
      if move.skillName == skel.name then return false end
      if move.toArea == Card.PlayerHand and move.to == player then return true end
      if move.from == player and table.find(move.moveInfo, function (info)
        return info.fromArea == Card.PlayerHand
      end) then return true end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local num = modeValue(player)
    if not num then return end
    local mark = player:getTableMark("@emo__ziduolh_mode")
    table.removeOne(mark, num)
    if #mark == 0 then return end
    table.sort(mark)
    mark = table.map(mark, tostring)
    num = tonumber(room:askToChoice(player, {
      choices = mark, skill_name = skel.name, prompt = "#emo__ziduolh-choice"
    }))
    num = player:getHandcardNum() - num
    if num > 0 then
      room:askToDiscard(player, {min_num = num, max_num = num, include_equip = false, skill_name = skel.name, cancelable = false})
    else
      player:drawCards(-num, skel.name)
    end
  end,
})
--]]

-- 众数记录器
skel:addEffect(fk.AfterCardsMove, {
  can_refresh = function(self, event, target, player, data)
    if not player:hasSkill(skel.name, true) or not modeValue(player) then return false end
    for _, move in ipairs(data) do
      if move.toArea == Card.PlayerHand then return true end
      for _, info in ipairs(move.moveInfo) do
        if info.fromArea == Card.PlayerHand then
          return true
        end
      end
    end
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addTableMarkIfNeed(player, "@emo__ziduolh_mode", modeValue(player))
  end,
})

-- 众数记录器2
skel:addEffect(fk.GameStart, {
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(skel.name, true) and modeValue(player)
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addTableMarkIfNeed(player, "@emo__ziduolh_mode", modeValue(player))
  end,
})

-- 众数记录器3
skel:addAcquireEffect(function (self, player, is_start)
  if is_start then return end -- 开局手牌为0
  local num = modeValue(player)
  if num then
    player.room:addTableMarkIfNeed(player, "@emo__ziduolh_mode", num)
  end
end)

skel:addLoseEffect(function (self, player, is_death)
  player.room:setPlayerMark(player, "@emo__ziduolh_mode", 0)
end)

return skel
